﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using LAIR.ResourceAPIs.WordNet;

namespace SearchingWebServices
{
    public partial class MainWindow : Form
    {
        private static readonly List<string> ServiceUrlList = new List<string>
                              {
                                  "http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl",
                                  "http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl",
                                  "http://www.restfulwebservices.net/wcf/CurrencyService.svc?wsdl"
                              };

        private static readonly Dictionary<string, Tuple<List<ServiceDefinition>, List<string>, Dictionary<string, float>>> ServiceDictionary = new Dictionary<string, Tuple<List<ServiceDefinition>, List<string>, Dictionary<string, float>>>();

        private static readonly List<Tuple<string, SynSet>> DomainNameList = new List<Tuple<string, SynSet>>
        {
            Tuple.Create("communication", WordNet.GetMostCommonSynSet("communication")),
            Tuple.Create("economy", WordNet.GetMostCommonSynSet("economy")),
            Tuple.Create("education", WordNet.GetMostCommonSynSet("education")),
            Tuple.Create("food", WordNet.GetMostCommonSynSet("food")),
            Tuple.Create("medical", WordNet.GetMostCommonSynSet("medical")),
            Tuple.Create("travel", WordNet.GetMostCommonSynSet("travel")),
            Tuple.Create("weather", WordNet.GetMostCommonSynSet("weather"))
        }; 

        public MainWindow()
        {
            InitializeComponent();
            //var blargh = Tokenizer.Tokenize("searchingWebServices andStuff with1MoreStuff thenThingsAreCool_acroNYMYay_ENDACRO");
            //var lemma = new LemmatizerPrebuiltCompact(LanguagePrebuilt.English);
            //var blah = lemma.Lemmatize("blarghed");
            //var bleh = WsdlParser.Parse("http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl");
            ////"http://www.weather.gov/forecasts/xml/DWMLgen/wsdl/ndfdXML.wsdl");
            ////"http://www.restfulwebservices.net/wcf/CurrencyService.svc?wsdl");
            //var tokens = WsdlParser.TokenizeServiceInfo(bleh);

            foreach (var serviceUrl in ServiceUrlList)
            {
                var serviceDefs = WsdlParser.Parse(serviceUrl);
                if (serviceDefs.Count > 0)
                {
                    var serviceTokens = WsdlParser.TokenizeServiceInfo(serviceDefs);
                    var simVals = BuildDomainSimilarities(serviceTokens);
                    ServiceDictionary.Add(serviceUrl, Tuple.Create(serviceDefs, serviceTokens, simVals));
                }
            }
        }

        private void SearchButton_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(QueryTextBox.Text))
            {
                return;
            }

            var wordSet = new HashSet<string>();

            foreach (var word in Tokenizer.Tokenize(QueryTextBox.Text).Where(word => !wordSet.Contains(word)))
            {
                wordSet.Add(Tokenizer.Lemmatizer.Lemmatize(word));
            }

            var domDict = DomainNameList.ToDictionary<Tuple<string, SynSet>, string, float>(domain => domain.Item1, domain => 0);
            foreach (var word in wordSet)
            {
                var wordSyn = WordNet.GetMostCommonSynSet(word);
                if (wordSyn == null)
                {
                    continue;
                }

                foreach (var domain in DomainNameList)
                {
                    domDict[domain.Item1] += WordNet.ComputeSimilarity(wordSyn, domain.Item2);
                }
            }

            foreach (var sim in domDict.ToList())
            {
                domDict[sim.Key] = sim.Value / wordSet.Count;
            }

            var domOrder = domDict.OrderByDescending(kvp => kvp.Value);
            var servOrder = ServiceDictionary.OrderByDescending(kvp => kvp.Value.Item3.First(kvp2 => kvp2.Key.Equals(domOrder.First().Key)).Value);

            var i = 1;
            var html = new StringBuilder("<ol><table width=\"95%\">");
            foreach (var serv in servOrder)
            {
                var servDef = serv.Value.Item1.First();
                html.AppendFormat("<tr><td>{3}.&nbsp;&nbsp;</td><td><b>{0}</b></td><td align=\"right\"><a href=\"{1}\">{1}</a></td></tr><tr><td></td><td colspan=\"2\">Description: {2}</td></tr>", servDef.Name, serv.Key, !string.IsNullOrWhiteSpace(servDef.Description) ? servDef.Description.Substring(0, 200) + "..." : string.Empty, i++);
            }
            html.Append("</table></ol>");
            Browser.DocumentText = html.ToString();
        }

        private Dictionary<string, float> BuildDomainSimilarities(List<string> wordList)
        {
            var domDict = DomainNameList.ToDictionary<Tuple<string, SynSet>, string, float>(domain => domain.Item1, domain => 0);

            foreach (var word in wordList)
            {
                var wordSyn = WordNet.GetMostCommonSynSet(word);
                if (wordSyn == null)
                {
                    continue;
                }

                foreach (var domain in  DomainNameList)
                {
                    domDict[domain.Item1] += WordNet.ComputeSimilarity(wordSyn, domain.Item2);
                }
            }

            foreach (var sim in domDict.ToList())
            {
                domDict[sim.Key] = sim.Value / wordList.Count;
            }
            return domDict;
        }
    }
}
